﻿using RuYiAdmin.Net.Common.CommonClass.CaptchaPicture;
using RuYiAdmin.Net.Common.Global;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RuYiAdmin.Net.Common.Utility
{
    /// <summary>
    /// 验证码工具类
    /// </summary>
    public class CaptchaUtil
    {
        /// <summary>
        /// 生产验证码
        /// </summary>
        /// <returns></returns>
        public static Captcha GenerateCaptcha()
        {
            var captcha = new Captcha();

            captcha.Id = Guid.NewGuid();

            var oper = GetOperator();

            var arr = GetNumber(oper);

            var firstNum = arr[0];
            var secondNum = arr[1];

            var resultNum = GetResult(firstNum, secondNum, oper);

            var strCode = firstNum.ToString() + oper + secondNum.ToString() + "=";

            captcha.CaptchaPicture = CreateImg(strCode);

            RedisUtil.Set(captcha.Id.ToString(), resultNum, GlobalContext.JwtSettings.SaltExpiration);

            return captcha;
        }

        /// <summary>
        /// 随机获取运算符
        /// </summary>
        /// <returns></returns>
        private static string GetOperator()
        {
            string OperatorArray = "+,-,×,÷";
            String[] VcArray = OperatorArray.Split(',');
            Random random = new Random();
            int iNum = random.Next(VcArray.Length);
            return VcArray[iNum];
        }

        /// <summary>
        /// 随机获取数并添加到数组
        /// </summary>
        /// <returns></returns>
        private static int[] GetNumber(string oper)
        {
            int[] numList = new int[2];
            string OperatorArray = "1,2,3,4,5,6,7,8,9,10";
            String[] VcArray = OperatorArray.Split(',');
            Random random = new Random();
            int iNum = random.Next(VcArray.Length);
            int iNum1 = random.Next(VcArray.Length);
            if (oper == "-" || oper == "÷")
            {
                numList[0] = Convert.ToInt32(VcArray[iNum]);
                numList[1] = Convert.ToInt32(VcArray[iNum1]);
                if (oper == "÷")
                {
                    while (true)
                    {
                        //必须整除
                        if (numList[0] > numList[1] && numList[0] % numList[1] == 0)
                        {
                            break;
                        }

                        iNum = random.Next(VcArray.Length);
                        iNum1 = random.Next(VcArray.Length);

                        numList[0] = Convert.ToInt32(VcArray[iNum]);
                        numList[1] = Convert.ToInt32(VcArray[iNum1]);
                    }
                }
            }
            else
            {
                numList[0] = Convert.ToInt32(VcArray[iNum]);
                numList[1] = Convert.ToInt32(VcArray[iNum1]);
            }
            return numList;
        }

        /// <summary>
        /// 获取运算结果
        /// </summary>
        /// <param name="firstNum"></param>
        /// <param name="secondNum"></param>
        /// <param name="oper"></param>
        /// <returns></returns>
        private static int GetResult(int firstNum, int secondNum, string oper)
        {
            int result = 0;
            switch (oper)
            {
                case "+":
                    result = firstNum + secondNum;
                    break;
                case "-":
                    result = firstNum - secondNum;
                    break;
                case "×":
                    result = firstNum * secondNum;
                    break;
                case "÷":
                    result = firstNum / secondNum;
                    break;
            }
            return result;
        }

        /// <summary>
        /// 生成图象
        /// </summary>
        /// <param name="strCode">随机数</param>
        private static String CreateImg(string strCode)
        {
            var width = 60;
            var height = 25;

            //颜色列表，用于验证码、噪线、噪点 
            Color[] color = { Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.Brown, Color.DarkBlue };

            Bitmap bitMapImage = new Bitmap(width, height);

            Graphics graphicImage = Graphics.FromImage(bitMapImage);

            //消除锯齿
            graphicImage.TextRenderingHint = TextRenderingHint.AntiAlias; 

            graphicImage.FillRectangle(new SolidBrush(Color.White), 0, 0, 60, 25);

            //设置画笔的输出模式
            graphicImage.SmoothingMode = SmoothingMode.HighSpeed;

            //画图片的前景噪音点
            Random randomPixel = new Random();

            Color clr = new Color();

            //画噪线 
            for (int i = 0; i < 4; i++)
            {
                int x1 = randomPixel.Next(bitMapImage.Width);
                int y1 = randomPixel.Next(bitMapImage.Height);
                int x2 = randomPixel.Next(bitMapImage.Width);
                int y2 = randomPixel.Next(bitMapImage.Height);
                clr = color[randomPixel.Next(color.Length)];
                graphicImage.DrawLine(new Pen(clr), x1, y1, x2, y2);
            }

            clr = color[randomPixel.Next(color.Length)];

            //添加文本字符串
            graphicImage.DrawString(strCode, new Font("Arial", 15, FontStyle.Italic), SystemBrushes.WindowText, new Point(0, 0));            

            for (int i = 0; i < 255; i++)
            {
                int x = randomPixel.Next(bitMapImage.Width);
                int y = randomPixel.Next(bitMapImage.Height);             
                bitMapImage.SetPixel(x, y, Color.FromArgb(randomPixel.Next(0, 255), randomPixel.Next(0, 255), randomPixel.Next(0, 255)));
            }

            var base64Str = BitmapUtil.ToBase64(bitMapImage);

            //释放占用的资源
            graphicImage.Dispose();
            bitMapImage.Dispose();

            return base64Str;
        }
    }
}
